package com.vlyman.captcha.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 类描述：</br>
 * 	数学处理通用工具类
 * @author chenjs
 * @date: 2016年11月20日
 */
public class MathUtils {

	/**
	 * 方法描述：<br>
	 * 	获取范围内的任意正整数，[min,max)
	 * @author: chenjs
	 * @param min
	 * @param max
	 * @return
	 * @date: 2016年11月20日
	 */
	public static int getRandomIntByRange(int min, int max){
		Random rand = new Random();
		return rand.nextInt(max-min)+min;
	}

	/**
	 * 方法描述：
	 *   产生0--num的随机数,不包括num
	 *  @author chenjs
	 *  @param num 数字
	 *  @return 
	 *  @date 2018/12/21 17:57
	 */
	public static int getRandomInt(int num){
		Random rand = new Random();
		return rand.nextInt(num);
	}
	
	/**
	 * 方法描述：<br>
	 * 	获取范围内的不重复的任意正整数，[min,max)-单边界
	 * @author: chenjs
	 * @param min 最小边界-结果包含
	 * @param max 最大边界-结果不包含
	 * @param num 抽取数量
	 * @return
	 * @date: 2016年11月20日
	 */
	public static Integer[] getSecureRandomIntByRange(int min, int max, int num){
		if (num > (max - min)) {
			//处理抽取数量大于范围造成的无限循环bug
			return getRandomOrderInRange(min, max);
		}
		Integer[] rtnArr = new Integer[num];
		for (int i = 0; i < num; i++) {
			Random rand = new Random();
			rtnArr[i] = rand.nextInt(max-min)+min;
			if (i == 0) {
				continue;
			}
			for (int j = 0; j < i; j++) {
				if (rtnArr[i].equals(rtnArr[j])) {
					i--;
				}
			}
		}
		return rtnArr;
	}

	/**
	 * 方法描述：
	 *   获得该范围内的整数乱序，[min, max)
	 *  @author chenjs
	 *  @param min 最小边界-结果包含
	 *  @param max 最大边界-结果不包含
	 *  @return
	 *  @date 2018/12/14 16:32
	 */
	public static Integer[] getRandomOrderInRange(int min, int max) {
		List<Integer> list = new ArrayList<Integer>(max - min);
		for (int i = min; i < max; i++) {
			list.add(i);
		}
		Collections.shuffle(list);
		Integer[] rtnArr = new Integer[list.size()];
		rtnArr = list.toArray(rtnArr);
		return rtnArr;
	}

	/**
	 * 方法描述：
	 *   随机抽取列表中元素
	 *  @author chenjs
	 *  @param sourceList	原列表
	 *  @param num			抽取数量
	 *  @param needDelete	是否删除抽出元素
	 *  @return
	 *  @date 2018/11/23 16:37
	 */
	public static <T> List<T> getSecureRandomElement(List<T> sourceList, int num, boolean needDelete){
		if (num == sourceList.size()) {
			return sourceList;
		}
		List<T> rtnList = new ArrayList<T>(num);
		Integer[] indexArr = getSecureRandomIntByRange(0, sourceList.size(), num);
		for (Integer index : indexArr) {
			rtnList.add(sourceList.get(index));
		}
		if (needDelete) {
			sourceList.removeAll(rtnList);
		}
		return rtnList;
	}
	
	/**
	 * 方法描述：<br>
	 * 	字符串转换整数
	 * @author: chenjs
	 * @param str
	 * @return
	 * @date: 2017年7月22日
	 */
	public static int stringToInt(String str){
		int rtnInt = 0;
		try {
			return Integer.valueOf(str);
		} catch (Exception e) {
			// TODO: handle exception
			return rtnInt;
		}
	}

	/**
	 * 方法描述：<br>
	 * 	计算百分比(四舍五入)，输出带%的字符串
	 * @author: chenjingshen
	 * @param numerator		分子
	 * @param denominator	分母
	 * @param scale			保留位数
	 * @return
	 * @date: 2017年12月7日
	 */
	public static String calculatePercentage(Integer numerator, Integer denominator, Integer scale){
		if (numerator == null || denominator == null || denominator == 0) {
			return "/";
		}
		Double denominatorD = Double.valueOf(denominator+"");
		Double percentage = new BigDecimal(numerator/denominatorD*100).setScale(scale, RoundingMode.UP).doubleValue();
		return percentage.toString()+"%";
	}

	/**
	 * 方法描述：
	 * 	将BigDecimal放大倍数，取整
	 * 	PS.用于微信支付结算元转分
	 * @author chenjs
	 * @param target
	 * @param times
	 * @return
	 * @date 2018/4/24
	 */
	public static Long bigDecimalLongValue(BigDecimal target, Integer times){
		target = target.multiply(new BigDecimal(times));
		return target.longValue();
	}
}
